package hu.elte.inf.holiuml.fileutil;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Vector;

import javax.xml.bind.annotation.XmlRootElement;

import hu.elte.inf.holiuml.gui.HoliUML;
import hu.elte.inf.holiuml.model.ClassDiagram;
import hu.elte.inf.holiuml.model.ClassNode;
import hu.elte.inf.holiuml.model.CollaborationDiagram;
import hu.elte.inf.holiuml.model.Document;
import hu.elte.inf.holiuml.model.RelationEdge;
import hu.elte.inf.holiuml.model.UMLClass;

/**
 * Class for XML Bindig. Only used inside this package.
 * This way there is no need to put JAXB specific annotations
 * on model classes, and all XML references logic remains in this package.
 *  
 * @author Jozsef Sipos
 *
 */
@XmlRootElement
class HoliUMLDocument {
	
	private Document document;
	private byte[] bindingHelper;
	
	HoliUMLDocument() {
		this(null);
	}
	
	HoliUMLDocument(Document document) {
		setDocument(document);
	}

	public void setDocument(Document document) {
		this.document = document;
	}
	
	public void generateReferenceInfo() {
		try {
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			ObjectOutputStream oos = new ObjectOutputStream(baos);
			oos.writeObject(document);
			oos.close();
			bindingHelper = baos.toByteArray();
			baos.close();
		} catch(IOException ioEx) {
			// Shouldn't happen
			System.err.println("Unable to serialize Document, will not be able to fully restore.");
			ioEx.printStackTrace();
		}
	}

	public Document getDocument() {
		return document;
	}

	public void restoreReferences() {
		try {
			ByteArrayInputStream bais = new ByteArrayInputStream(bindingHelper);
			ObjectInputStream ois = new ObjectInputStream(bais);
			document = (Document)ois.readObject();
			ois.close();
			bais.close();
		} catch (IOException e) {
			// Shouldn't happen
			System.err.println("Unable to deserialize Document");
		} catch (ClassNotFoundException e) {
			throw new RuntimeException(e);
		}
		
		// Restoring transient fields
		for(ClassDiagram cd : document.getClassDiagram()) {
			cd.setMain(HoliUML.getMain());
		}
		for(CollaborationDiagram cd : document.getCollaborationDiagram()) {
			cd.setMain(HoliUML.getMain());
		}
	}

	public void setBindingHelper(byte[] bindingHelper) {
		this.bindingHelper = bindingHelper;
	}

	public byte[] getBindingHelper() {
		return bindingHelper;
	}
}
